﻿using System.Collections.Generic;

namespace CST_276_Lab_3
{
    public class AutomationController : ISubject
    {

        #region Members
        private static volatile AutomationController _uniqueInstance;
        private static readonly object SyncRoot = new object();
        private readonly List<IObserver> _observers;
        private Queue<DeskOrder> _deskOrders;
        #endregion

        #region Methods

        public List<Desk> CompletedDesks { get; set; }

        private AutomationController()
        {
            this._observers = new List<IObserver>();
            this._deskOrders = new Queue<DeskOrder>();
            this.CompletedDesks = new List<Desk>();
        }

        public static AutomationController GetInstance()
        {
            if (_uniqueInstance == null)
            {
                lock (SyncRoot)
                {
                    if (_uniqueInstance == null)
                    {
                        _uniqueInstance = new AutomationController();
                    }
                }
            }

            return _uniqueInstance;
        }

        public void RegisterObserver(IObserver o)
        {
            this._observers.Add(o);
        }

        public void RemoveObserver(IObserver o)
        {
            if (this._observers.Contains(o)) { this._observers.Remove(o); }
        }

        public void NotifyObserver()
        {
            while (_deskOrders.Count != 0)
            {
                foreach (IObserver o in this._observers)
                {
                    var completedDesk = o.Update(ref _deskOrders);

                    if (completedDesk != null)
                    {
                        this.CompletedDesks.Add(completedDesk);
                    }
                }
            }
        }

        public void OrdersChanged() { this.NotifyObserver(); }

        public void AddDeskOrders(Queue<DeskOrder> newOrders)
        {
            foreach (var deskOrder in newOrders)
            {
                _deskOrders.Enqueue(deskOrder);
            }

            OrdersChanged();
        }

        #endregion

    }
}